//
//  SPPreferencesController.m
//  Sophie
//
//  Created by Anton Chebotaev on 10/10/09.
//  Copyright 2009 IFMO. All rights reserved.
//

#import "SPAccountController.h"

@interface SPAccountController (Private)
+ (NSString *)applicationSupportDirectory;
- (NSString *)password;
- (void)accountDidReloadCallback:(NSNotification *)note;
- (void)livejournalErrorCallback:(NSNotification *)note;
@end

#pragma mark -

@implementation SPAccountController

@synthesize sharedAccount;
@synthesize operationQueue;

#pragma mark Life Cycle
- (id)init {
	if (self = [super init]) {
		operationQueue = [[NSOperationQueue alloc] init];
		sharedAccount = nil;

		[[NSNotificationCenter defaultCenter] addObserver:self
												 selector:@selector(accountDidReloadCallback:)
													 name:LJAccountDidUpdateNotification
												   object:nil];	
		[[NSNotificationCenter defaultCenter] addObserver:self
												 selector:@selector(livejournalErrorCallback:)
													 name:LJServerLivejournalErrorNotification
												   object:nil];	
	}
	return self;
}

- (void)dealloc {
	if (sharedAccount) {
		[sharedAccount release];
	}
	[[NSNotificationCenter defaultCenter] removeObserver:self];
	[operationQueue release];
	[super dealloc];
}

static SPAccountController *sharedAccountController = nil;
+ (SPAccountController *)sharedController {
	@synchronized(self) {
		if (sharedAccountController == nil) {
			[[self alloc] init]; // assignment not done here //NOTE:Why?
		}
	}
	return sharedAccountController;
}

+ (id)allocWithZone:(NSZone *)zone {
	@synchronized(self) {
		if (sharedAccountController == nil) {
			sharedAccountController = [super allocWithZone:zone];
			return sharedAccountController;
		}
	}
	return nil; // on subsequent allocation attempts return nil
}

- (id)copyWithZone:(NSZone *)zone {
	return self;
}

- (id)retain {
	return self;
}

- (void)release {
	// do nothing
}

- (id)autorelease {
	return self;
}

#pragma mark Account messages

- (void)loadAccountFromDisk {
	
	NSString *defaultUsername = [[SPPreferencesController sharedController] defaultUsername];
	
	NSString *filename = [NSString stringWithFormat:@"%@/%@.livejournalaccount",
						  [SPAccountController applicationSupportDirectory], defaultUsername];

	[self willChangeValueForKey:@"sharedAccount"];
	@synchronized(sharedAccount) {
		sharedAccount = [[NSKeyedUnarchiver unarchiveObjectWithFile:filename] retain];	
	}
	[self didChangeValueForKey:@"sharedAccount"];
}
- (void)saveAccountToDisk {
	NSString *folder = [SPAccountController applicationSupportDirectory];
	if ([[NSFileManager defaultManager] fileExistsAtPath:folder] == NO)
	{
		[[NSFileManager defaultManager] createDirectoryAtPath:folder
								  withIntermediateDirectories:NO
												   attributes:nil
														error:nil];
	}
	
	NSString *filename = [NSString stringWithFormat:@"%@/%@.livejournalaccount", folder, [sharedAccount username]];

	@synchronized(sharedAccount) {
		[NSKeyedArchiver archiveRootObject:sharedAccount toFile:filename];
	}
}

- (void)reloadFromServerWithUsername:(NSString*)aUsername {
	if ([aUsername isCaseInsensitiveLike:[sharedAccount username]]) {
		return;
	}

	[self willChangeValueForKey:@"sharedAccount"];
	[sharedAccount release];
	@synchronized(sharedAccount) {
		sharedAccount = [[LJAccount alloc] initWithUsername:aUsername];	
	}
	[self didChangeValueForKey:@"sharedAccount"];
	
	[[SPPreferencesController sharedController] setDefaultUsername:aUsername];

	[self updateFromServer];
}

- (void)updateFromServer {
	NSOperation* updateAccount = [sharedAccount updateFromServerOperation:[self password]];
	[operationQueue addOperation: updateAccount];
	[operationQueue waitUntilAllOperationsAreFinished];
	
	NSOperation* updateUserpics = [sharedAccount reloadUserpicsImagesOperation];
	[updateUserpics addDependency:updateAccount];
	[operationQueue addOperation: updateUserpics];	
	
	NSOperation* updateFriends = [sharedAccount updateFriendsOperation:[self password]];	
	[updateFriends addDependency:updateAccount];
	[operationQueue addOperation: updateFriends];	
	
	NSOperation* updateTags = [sharedAccount updateTagsOperation:[self password]];	
	[updateTags addDependency:updateAccount];
	[operationQueue addOperation: updateTags];	
}

- (void)postEntry:(LJEntry*)entry {
	[operationQueue addOperation: [entry postOperation:[self password]]];
}

@end

@implementation SPAccountController (Private)

- (void)accountDidReloadCallback:(NSNotification *)note {
	[self saveAccountToDisk];
}

- (void)livejournalErrorCallback:(NSNotification *)note {
	[operationQueue cancelAllOperations];
}

+ (NSString*)applicationSupportDirectory {
	
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
	if ([paths count] > 0) {
		NSString* basePath = [paths objectAtIndex:0];
		return [basePath stringByAppendingPathComponent:@"Sophie"];
	} else {
		return nil;
	}
}

- (NSString *)password {
	EMInternetKeychainItem *ki = [[EMKeychainProxy sharedProxy] internetKeychainItemForServer:@"livejournal.com"
																				 withUsername:[sharedAccount username]
																						 path:@""
																						 port:80
																						protocol:kSecProtocolTypeHTTP];
	return [ki password];
}
@end
